﻿/// <reference path="../../mapparola.client/scripts/typings/jquery/jquery.d.ts" />
/// <reference path="../../mapparola.core/mapparolacore.d.ts" />

module Mapparola.Core.Client {

    export class RestDataStore {

        private headerRequest: string;
        private debug: boolean = true;

        constructor() {
            this.headerRequest = "http://localhost:8080";
        }


        private ExecuteAjax(internals: _AjaxInternals, args?: AjaxRequestArgs): any {

            try {

                var ajaxRequest = this.headerRequest + internals.request;

                var body = "";

                if (internals.httpVerb === Core.RestType[Core.RestType.POST] ||
                    internals.httpVerb === Core.RestType[Core.RestType.PUT] ||
                    internals.httpVerb === Core.RestType[Core.RestType.DELETE]) {
                    body = JSON.stringify(internals.data);
                }

                $.ajax({
                    type: internals.httpVerb,
                    url: ajaxRequest,
                    async: true,
                    contentType: "application/json; charset=utf-8",
                    //dataType: "json",
                    data: body,
                    xhrfields: {
                        withcredentials: true
                    },
                    crossDomain: true,
                    beforeSend: (jqXHR: JQueryXHR, settings: any) => {

                        if (args && args.beforeSend) {
                            args.beforeSend(jqXHR, settings);
                        }
                    },
                    success: (items: any, textStatus: string, jqXHR: JQueryXHR) => {

                        //If there is a success callback
                        if (args && args.success) {

                            args.success(items, textStatus, jqXHR);
                        }
                    },
                    error: (jqXHR: JQueryXHR, textStatus: string, errorThrown: string) => {

                        if (this.debug) {
                            console.log(JSON.stringify(jqXHR));
                        }

                        if (jqXHR.status === 502 || jqXHR.status === 0) {
                            //We offline

                            if (args && args.error) {

                                args.error(jqXHR, textStatus, errorThrown);
                            }
                        }
                        else {
                            if (args && args.error) {

                                args.error(jqXHR, textStatus, errorThrown);
                            }
                        }
                    }
                });
            }

            catch (err) {
                throw err;
            }
        }

        public CurrentUser(args: AjaxRequestArgs): void {

            var auth = new Mapparola.Core.AuthenticationGet();

            var internals: _AjaxInternals = {
                request: auth._serverProperties.partialUrl,
                httpVerb: Mapparola.Core.RestType[auth.type],
            }

            this.ExecuteAjax(internals, args);
        }

        public Authenticate(loginArgs: Core.LoginArgs, args: AjaxRequestArgs): void {

            var auth = new Mapparola.Core.AuthenticationPost();

            var internals: _AjaxInternals = {
                request: auth._serverProperties.partialUrl,
                httpVerb: Mapparola.Core.RestType[auth.type],
                data: loginArgs
            }

            this.ExecuteAjax(internals, args);
        }

        public GetPersonalDiscussions(args: AjaxRequestArgs): void {

            var restObj = new Mapparola.Core.PersonalDiscussionsGet();

            var internals: _AjaxInternals = {
                request: restObj._serverProperties.partialUrl,
                httpVerb: Mapparola.Core.RestType[restObj.type]
            }

            this.ExecuteAjax(internals, args);
        }

        public FavoriteDiscussions(msgToken: string, args: AjaxRequestArgs): void {

            var restObj = new Mapparola.Core.PersonalDiscussionPost();

            var internals: _AjaxInternals = {
                request: restObj._serverProperties.partialUrl,
                httpVerb: Mapparola.Core.RestType[restObj.type],
                data: msgToken
            }

            this.ExecuteAjax(internals, args);
        }

        public PostNewDiscussion(discussion: Core.Discussion, args: AjaxRequestArgs): void {

            var restObj = new Mapparola.Core.DiscussionPost();

            var internals: _AjaxInternals = {
                request: restObj._serverProperties.partialUrl,
                httpVerb: Mapparola.Core.RestType[restObj.type]
            }

            internals.data = discussion;

            this.ExecuteAjax(internals, args);
        }

        public MarkDiscussionAsSeen(args: AjaxRequestArgs): void {

            var restObj = new Mapparola.Core.PersonalDiscussionsGet();

            var internals: _AjaxInternals = {
                request: restObj._serverProperties.partialUrl,
                httpVerb: Mapparola.Core.RestType[restObj.type]
            }

            this.ExecuteAjax(internals, args);
        }

        public GetNewDiscussionsAroundMe(point: Core.Point, args: AjaxRequestArgs): void {

            var restObj = new Mapparola.Core.NewDiscussionsGet();

            var internals: _AjaxInternals = {
                request: restObj._serverProperties.partialUrl + "?data=" + JSON.stringify(point),
                httpVerb: Mapparola.Core.RestType[restObj.type]
            };

            if (args.success) {

                var succCallback = args.success;
                var discussions: Client.DiscussionC[] = [];

                //Define json converter
                args.success = (items?: any[], textStatus?: string, jqXHR?: JQueryXHR) => {

                    items.forEach((value: any) => {
                        discussions.push(Client.DiscussionC.FromServerObject(value));
                    });

                    succCallback(discussions, textStatus, jqXHR);

                }
            }


            this.ExecuteAjax(internals, args);
        }

        public DeleteAllMessages(args?: AjaxRequestArgs): void {

            var internals: _AjaxInternals = {
                request: "/discussion/DEL/deleteAll",
                httpVerb: Mapparola.Core.RestType[Core.RestType.DELETE]
            };

            this.ExecuteAjax(internals, args);

        }
    }

    interface _AjaxInternals {
        data?: any;
        httpVerb: string;
        request: string;
    }
}